package start.aai.utils;

import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.Tesseract;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import start.aai.entity.DTO.FileDTO;

import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Base64;

@Slf4j
public class FileProcessor {

    private static final String BASE_FILE_URL = "http://localhost:8080/files/";

    private static final Tesseract tesseract = new Tesseract();
    static {
        tesseract.setDatapath("src/main/resources/tessdata");
        tesseract.setLanguage("chi_sim+eng");
    }

    // 图片转Base64
    public static String imageToBase64(MultipartFile file) throws IOException {
        if (!isImageFile(file.getOriginalFilename())) {
            throw new IllegalArgumentException("非图片文件");
        }
        byte[] bytes = file.getBytes();
        return Base64.getEncoder().encodeToString(bytes);
    }

    public static boolean isImageFile(String fileName) {
        if (fileName == null) return false;
        String[] imgExts = {".jpg", ".jpeg", ".png", ".gif"};
        return Arrays.stream(imgExts).anyMatch(fileName.toLowerCase()::endsWith);
    }

    // 文件解析方法
    public static String pdfRead(InputStream inputStream) throws IOException {
        try (PDDocument document = PDDocument.load(inputStream)) {
            PDFTextStripper stripper = new PDFTextStripper();
            return stripper.getText(document).replaceAll("\\s+", " ").trim();
        }
    }

    public static String wordRead(InputStream inputStream) throws IOException {
        try (XWPFDocument document = new XWPFDocument(inputStream)) {
            StringBuilder text = new StringBuilder();
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                text.append(paragraph.getText()).append(" ");
            }
            return text.toString().replaceAll("\\s+", " ").trim();
        }
    }

    public static String excelRead(InputStream inputStream, String fileName) throws IOException {
        Workbook workbook;
        if (fileName.endsWith(".xlsx")) {
            workbook = new XSSFWorkbook(inputStream);
        } else if (fileName.endsWith(".xls")) {
            workbook = new HSSFWorkbook(inputStream);
        } else {
            throw new IllegalArgumentException("不支持的文件格式");
        }

        StringBuilder text = new StringBuilder();
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            Sheet sheet = workbook.getSheetAt(i);
            for (Row row : sheet) {
                for (Cell cell : row) {
                    switch (cell.getCellType()) {
                        case STRING:
                            text.append(cell.getStringCellValue()).append(" ");
                            break;
                        case NUMERIC:
                            text.append(cell.getNumericCellValue()).append(" ");
                            break;
                        case BOOLEAN:
                            text.append(cell.getBooleanCellValue()).append(" ");
                            break;
                        default:
                            text.append(" ");
                    }
                }
            }
        }
        return text.toString().replaceAll("\\s+", " ").trim();
    }

    public static String txtRead(InputStream inputStream) throws IOException {
        try (java.util.Scanner scanner = new java.util.Scanner(inputStream, StandardCharsets.UTF_8)) {
            StringBuilder text = new StringBuilder();
            while (scanner.hasNextLine()) {
                text.append(scanner.nextLine()).append(" ");
            }
            return text.toString().replaceAll("\\s+", " ").trim();
        }
    }

    public static String pictureRead(byte[] imageBytes) {
        try {
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
            return tesseract.doOCR(image).replaceAll("\\s+", " ").trim();
        } catch (Exception e) {
            throw new RuntimeException("图片解析失败", e);
        }
    }

    // 文件分类处理器
    public static String processFile(MultipartFile file, String fileName) throws IOException {
        if (fileName.endsWith(".txt") || fileName.endsWith(".md")) {
            return txtRead(file.getInputStream());
        } else if (fileName.endsWith(".pdf")) {
            return pdfRead(file.getInputStream());
        } else if (fileName.endsWith(".docx") || fileName.endsWith(".doc")) {
            return wordRead(file.getInputStream());
        } else if (fileName.endsWith(".xlsx") || fileName.endsWith(".xls")) {
            return excelRead(file.getInputStream(), fileName);
        } else if (isImageFile(fileName)) {
            return pictureRead(file.getBytes());
        } else {
            throw new IllegalArgumentException("不支持的文件类型: " + fileName);
        }
    }

    // 辅助方法
    public static String cleanContent(String content) {
        if (content == null) return "";
        return content
                .replaceAll("\\p{C}", "")
                .replaceAll("\\s+", " ")
                .replaceAll("\\n+", "\n")
                .replaceAll("[^\\u4E00-\\u9FFFa-zA-Z0-9\\p{Punct}\\n]", "");
    }

    public static String limitContentLength(String content, int maxLength) {
        return content.length() <= maxLength ?
                content : content.substring(0, maxLength) + "\n...（内容过长，已截断）";
    }
    //生成唯一文件名
    private static String generateUniqueFileName(String originalFileName) {
        String extension = "";
        int lastDotIndex = originalFileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            extension = originalFileName.substring(lastDotIndex);
        }
        return UUID.randomUUID().toString() + extension;
    }

    public static FileDTO saveFile(String fileName) throws IOException {
        String uniqueFileName = generateUniqueFileName(fileName);
        String fileUrl = BASE_FILE_URL + uniqueFileName;
        FileDTO fileDTO = new FileDTO();
        fileDTO.setFileName(uniqueFileName);
        fileDTO.setFileurl(fileUrl);
        return fileDTO;
    }
}